package cn.wangxl.vertx.starter.web.auth;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.PubSecKeyOptions;
import io.vertx.ext.auth.jwt.JWTAuth;
import io.vertx.ext.auth.jwt.JWTAuthOptions;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import io.vertx.ext.jwt.JWTOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.Session;
import io.vertx.ext.web.handler.AuthHandler;
import io.vertx.ext.web.handler.JWTAuthHandler;

/**
 * jwt:囊括所有认证信息，所以不需要session
 */
public class JWTTest extends AbstractVerticle {

  // 认证授权(根据需求配置不同的认证方式)
  JWTAuth authProvider = null;

  @Override
  public void start(Future<Void> startFuture) throws Exception {

    Vertx vertx = Vertx.vertx();
    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);

    JWTAuthOptions authConfig = new JWTAuthOptions()
      .addPubSecKey(new PubSecKeyOptions()
        .setAlgorithm("HS256")
        .setPublicKey("keyboard cat")
        .setSymmetric(true)
      );

    authProvider = JWTAuth.create(vertx, authConfig);
    AuthHandler jwtAuthHandler = JWTAuthHandler.create(authProvider);

    JWTCheckHandler jwtCheckHandler = new JWTCheckHandler(authProvider);

    router.post("/login").handler(ctx -> {
      // 认证通过之后，再生成token，以后就使用token进行认证
      JsonObject data = new JsonObject();
      data.put("username", "admin");
      data.put("password", "admin");
      String token = authProvider.generateToken(data, new JWTOptions());
      ctx.response().end(token);
    });

    router.route("/info")
      .handler(jwtCheckHandler)
      .handler(ctx -> {
        HttpServerRequest request = ctx.request();
        String jwt = ctx.request().getHeader("jwt");
        ctx.response().end("OK");
      });

    server.requestHandler(router).listen(9999, http -> {
      if (http.succeeded()) {
        startFuture.complete();
        System.out.println("HTTP server started on port 8888");
      } else {
        startFuture.fail(http.cause());
      }
    });
  }


  public static void main(String[] args) throws Exception {
//    System.setProperty("vertx.logger-delegate-factory-class-name","io.vertx.core.logging.Log4j2LogDelegateFactory");
    System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.Log4j2LogDelegateFactory");
    new JWTTest().start(Future.future());
  }


}
